﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Entities;
using Entities.Enums;
using Interview_Prov.Controls.Answers;

namespace Interview_Prov.Controls
{
    public partial class Question_Ctl : System.Web.UI.UserControl
    {
        public Entities.Question SrcQuestion { get; set; }
        public Entities.QuestionRunResultData Result { get; set; }
        public int RelativeQuestionNumber { get; set; }
        public bool EditMode { get; set; }
        private int total_counter = 0;

        protected string makeID(int index)
        {
            return string.Format("Question{0}_Answer{1}", this.RelativeQuestionNumber, index);
        }

        protected Control AddCheckBoxAnswer(int index)
        {
            index += total_counter;
            var newAnswer_ctl = (AnswerCheckBox)LoadControl("~\\Controls\\Answers\\AnswerCheckBox.ascx");
            newAnswer_ctl.ID = makeID(index);
            newAnswer_ctl.DeleteClicked += new EventHandler<AnswerEventArgs>(Answer_DeleteClicked);
            newAnswer_ctl.AnswerValueChanged += new EventHandler<AnswerEventArgs>(Answer_ValueChanged);
            newAnswer_ctl.AnswerIndex = index;
            newAnswer_ctl.AnswerLabel = "New Answer";
            newAnswer_ctl.EditMode = this.EditMode;
            if (!IsPostBack)
            {
                newAnswer_ctl.AnswerLabel = SrcQuestion.Answers[index - total_counter];
            }
            return newAnswer_ctl;
        }

        protected Control AddTextAnswer(int index)
        {
            index += total_counter;
            var newAnswer_ctl = (AnswerText)LoadControl("~\\Controls\\Answers\\AnswerText.ascx");
            newAnswer_ctl.ID = makeID(index);
            newAnswer_ctl.AnswerIndex = index;
            newAnswer_ctl.EditMode = this.EditMode;
            return newAnswer_ctl;
        }

        protected ListItem AddRadioButtonAnswer(int index)
        {
            index += total_counter;
            var newAnswer_ctl = new ListItem();
            newAnswer_ctl.Text = "New Answer";
            //newAnswer_ctl.ID = makeID(index);
            if (!IsPostBack)
            {
                newAnswer_ctl.Text = SrcQuestion.Answers[index - total_counter];
            }
            return newAnswer_ctl;
        }

        protected Control AddRadioButtonAnswer_Edit(int index)
        {
            index += total_counter;
            var newAnswer_ctl = (AnswerRadioButton)LoadControl("~\\Controls\\Answers\\AnswerRadioButton.ascx");
            newAnswer_ctl.ID = makeID(index);
            newAnswer_ctl.DeleteClicked += new EventHandler<AnswerEventArgs>(Answer_DeleteClicked);
            newAnswer_ctl.AnswerValueChanged += new EventHandler<AnswerEventArgs>(Answer_ValueChanged);
            newAnswer_ctl.AnswerIndex = index;
            newAnswer_ctl.AnswerLabel = "New Answer";
            newAnswer_ctl.EditMode = this.EditMode;
            if (!IsPostBack)
            {
                newAnswer_ctl.AnswerLabel = SrcQuestion.Answers[index - total_counter];
            }
            return newAnswer_ctl;
        }

        // Delete answer button handler
        void Answer_DeleteClicked(object sender, AnswerEventArgs e)
        {
            SrcQuestion.Answers.RemoveAt(e.AnswerIndex);
            if (SrcQuestion.Type == QuestionType.MultipleChoice)
            {
                this.answers_ph.Controls.Remove(answers_ph.FindControl(makeID(e.AnswerIndex)));
            }
            else if (SrcQuestion.Type == QuestionType.SingleChoice)
            {
                this.answers_ph.Controls.Remove(answers_ph.FindControl(makeID(e.AnswerIndex)));
            }
            SrcQuestion.ChgState = Entities.Enums.EntityState.Changed;
        }

        void Answer_ValueChanged(object sender, AnswerEventArgs e)
        {
            SrcQuestion.Answers[e.AnswerIndex] = e.NewValue;
            SrcQuestion.ChgState = Entities.Enums.EntityState.Changed;
        }

        // Viewstate for answers reload on postback
        private string _viewstate_key
        {
            get
            {
                return string.Format("Answers_{0}", RelativeQuestionNumber);
            }
        }
        private List<QuestionType> _answers;
        private bool _answers_loaded_from_viewstate = false;
        private List<QuestionType> Answers
        {
            get
            {
                if (!_answers_loaded_from_viewstate)
                {
                    _answers_loaded_from_viewstate = true;
                    if (ViewState[_viewstate_key] != null)
                    {
                        _answers = (List<QuestionType>)ViewState[_viewstate_key];
                        return _answers;
                    }
                    else
                    {
                        _answers = new List<QuestionType>();
                        return _answers;
                    }
                }
                else
                {
                    return _answers;
                }
            }
            set
            {
                _answers = value;
                ViewState[_viewstate_key] = _answers;
                _answers_loaded_from_viewstate = true;
            }
        }


        private delegate Control AddControlSpecial(int index);

        protected void InitializeControl()
        {
            this.question_type_editor.Visible = EditMode;
            this.question_type_editor.SelectedIndex = (int)SrcQuestion.Type;
            this.radio_answers.Visible = !EditMode;
            this.q_relative_number.Text = (RelativeQuestionNumber + 1).ToString();
            this.question_text.Text = SrcQuestion.QuestionText;
            this.q_text_editor.Text = SrcQuestion.QuestionText;
            this.q_text_editor.Visible = EditMode;
            this.question_text.Visible = !EditMode;
            this.add_answer_button.Visible = EditMode;
            this.delete_button.Visible = EditMode;
        }

        private AddControlSpecial GetAddAnswerDelegateForType()
        {
            AddControlSpecial AddControlFunc;
            switch (SrcQuestion.Type)
            {
                case QuestionType.MultipleChoice:
                    AddControlFunc = AddCheckBoxAnswer;
                    break;
                case QuestionType.SingleChoice:
                    AddControlFunc = AddRadioButtonAnswer_Edit;
                    break;
                case QuestionType.TextInput:
                default:
                    AddControlFunc = AddTextAnswer;
                    break;
            }
            return AddControlFunc;
        }

        protected override void OnInit(EventArgs e)
        {
            InitializeControl();

            AddControlSpecial AddControlFunc = GetAddAnswerDelegateForType();

            // Restoring answers from Question instance
            for (int i = 0; i < SrcQuestion.Answers.Count(); i++)
            {
                var ctl = AddControlFunc(i);
                if (ctl is AnswerCheckBox)
                {
                    answers_ph.Controls.Add((AnswerCheckBox)ctl);
                }
                else if (ctl is AnswerRadioButton)
                {
                    if (EditMode)
                    {
                        answers_ph.Controls.Add((AnswerRadioButton)ctl);
                    }
                    else
                    {
                        radio_answers.Items.Add(AddRadioButtonAnswer(i));
                    }
                }
                else if (ctl is AnswerText)
                {
                    answers_ph.Controls.Add((AnswerText)ctl);
                }
            }

            if (SrcQuestion.Type == QuestionType.TextInput && SrcQuestion.Answers.Count() == 0)
            {
                var tb_ctl = (AnswerText)AddControlFunc(0);
                answers_ph.Controls.Add(tb_ctl);
            }

            base.OnInit(e);
        }

        protected void Page_Load(object sender, EventArgs e)
        {

        }

        public event EventHandler<QuestionEventArgs> QuestionWithoutAnswerDetected;

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            if (IsPostBack && !EditMode)
            {
                //Saving parsed data to Result
                switch (SrcQuestion.Type)
                {
                    case QuestionType.MultipleChoice:
                        List<int> selected = new List<int>();
                        foreach (var ctl in answers_ph.Controls)
                        {
                            var chkbox = (AnswerCheckBox)ctl;
                            if (chkbox.Checked)
                            {
                                selected.Add(chkbox.AnswerIndex);
                            }
                        }
                        if (selected.Count() == 0 && QuestionWithoutAnswerDetected != null)     // We had to use validators but it's too much...
                        {
                            QuestionWithoutAnswerDetected(this, new QuestionEventArgs(RelativeQuestionNumber));
                        }
                        this.Result = new QuestionRunResultData(SrcQuestion.ID, selected, QuestionType.MultipleChoice);
                        break;
                    case QuestionType.SingleChoice:
                        if (radio_answers.SelectedIndex == -1 && QuestionWithoutAnswerDetected != null)
                        {
                            QuestionWithoutAnswerDetected(this, new QuestionEventArgs(RelativeQuestionNumber));
                        }
                        this.Result = new QuestionRunResultData(SrcQuestion.ID, radio_answers.SelectedIndex, QuestionType.SingleChoice);
                        break;
                    case QuestionType.TextInput:
                        foreach (var ctl in answers_ph.Controls)
                        {
                            var tbox = (AnswerText)ctl;
                            if (tbox.AnswerResult == "" && QuestionWithoutAnswerDetected != null)
                            {
                                QuestionWithoutAnswerDetected(this, new QuestionEventArgs(RelativeQuestionNumber));
                            }
                            this.Result = new QuestionRunResultData(SrcQuestion.ID, tbox.AnswerResult);
                        }
                        break;
                    default:
                        this.Result = new QuestionRunResultData(SrcQuestion.ID, "NoAnswer");
                        break;
                }
                // End saving result
            }
        }

        public event EventHandler<QuestionEventArgs> QuestionTextChanged;

        protected void q_text_editor_TextChanged(object sender, EventArgs e)
        {
            if (QuestionTextChanged != null)
            {
                QuestionTextChanged(this, new QuestionEventArgs(this.RelativeQuestionNumber, q_text_editor.Text));
            }
            SrcQuestion.QuestionText = q_text_editor.Text;
            SrcQuestion.ChgState = Entities.Enums.EntityState.Changed;
        }


        protected void question_type_editor_SelectedIndexChanged(object sender, EventArgs e)
        {
            SrcQuestion.Answers = new List<string>();
            answers_ph.Controls.Clear();

            switch (question_type_editor.SelectedIndex)
            {
                case 0:
                    SrcQuestion.Type = QuestionType.MultipleChoice;
                    break;
                case 1:
                    SrcQuestion.Type = QuestionType.SingleChoice;
                    break;
                case 2:
                default:
                    SrcQuestion.Type = QuestionType.TextInput;
                    AddControlSpecial AddControlFunc = GetAddAnswerDelegateForType();
                    var tb_ctl = (AnswerText)AddControlFunc(0);
                    answers_ph.Controls.Add(tb_ctl);
                    break;
            }
            SrcQuestion.ChgState = Entities.Enums.EntityState.Changed;
        }

        protected void add_answer_button_Click(object sender, EventArgs e)
        {
            int index = SrcQuestion.Answers.Count();
            if (SrcQuestion.Type != QuestionType.TextInput)
            {
                if (SrcQuestion.Type == QuestionType.MultipleChoice)
                {
                    var ctl = (AnswerCheckBox)AddCheckBoxAnswer(index);
                    answers_ph.Controls.Add(ctl);
                    SrcQuestion.Answers.Add(ctl.AnswerLabel);
                    SrcQuestion.ChgState = Entities.Enums.EntityState.Changed;
                }
                if (SrcQuestion.Type == QuestionType.SingleChoice)
                {
                    var ctl = (AnswerRadioButton)AddRadioButtonAnswer_Edit(index);
                    answers_ph.Controls.Add(ctl);
                    SrcQuestion.Answers.Add(ctl.AnswerLabel);
                    SrcQuestion.ChgState = Entities.Enums.EntityState.Changed;
                }
            }
        }

        // Question delete button click event
        public event EventHandler<QuestionEventArgs> DeleteClicked;

        protected void delete_button_Click(object sender, EventArgs e)
        {
            if (DeleteClicked != null)
            {
                DeleteClicked(sender, new QuestionEventArgs(this.RelativeQuestionNumber));
            }
            SrcQuestion.ChgState = Entities.Enums.EntityState.Changed;
        }

    }
}